package tom.client.invoice;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import tom.client.DialogExec;
import tom.client.Library;
import tom.client.LookupInvDlg;
import tom.client.LookupDialog;
import tom.client.LookupInvRefund;
import tom.client.OverwriteLevel;
import tom.shared.Customer;
import tom.shared.InvItem;
import tom.shared.Invoice;
import tom.shared.Payment;
import tom.shared.Product;
import tom.shared.RReason;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.datepicker.client.CalendarUtil;
import com.google.gwt.user.datepicker.client.DateBox;
import com.google.gwt.user.datepicker.client.DateBox.DefaultFormat;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.ValueBoxBase.TextAlignment;
import com.google.gwt.user.client.ui.IntegerBox;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.user.client.ui.CheckBox;

public class FormInvRefund extends AbsolutePanel implements DialogExec {

	protected enum FormMode {
		Clear, Open, Edit, Insert
	};

	protected Library.FormMode mode = Library.FormMode.Clear;

	protected void setMode(Library.FormMode m) {
		mode = Library.checkPermission(m);
		lbFormMode.setText(m.toString());
		if (m == Library.FormMode.Clear) {
			btnContact.setEnabled(false);
			btnSearch.setEnabled(true);
			txtContCode.setEnabled(false);
			btnDelItem.setEnabled(false);
			btnPayRemove.setEnabled(false);
			txtSaleDate.setEnabled(false);
			txtShipDate.setEnabled(false);
			txtDueDate.setEnabled(false);
			txtProject.setEnabled(false);
			txtPrjCode.setEnabled(false);
			txtAddr.setEnabled(false);
			txtShipTo.setEnabled(false);
			txtComment.setEnabled(false);
			txtDocRef.setEnabled(false);
			txtCustomer.setEnabled(false);
			txtCode.setEnabled(false);
			txtStatus.setEnabled(false);
			txtBalance.setEnabled(false);
			txtTotalItem.setEnabled(false);
			txtTotalVat.setEnabled(false);
			txtTotalAmt.setEnabled(false);
			txtReTotalItem.setEnabled(false);
			txtDiscount.setEnabled(false);
			boxPayAmt.setEnabled(false);
			txtPayMethod.setEnabled(false);
			txtCheck.setEnabled(false);
			txtPayMeth.setEnabled(false);
			boxCheckDate.setEnabled(false);
			txtProCode.setEnabled(false);
			txtProName.setEnabled(false);
			boxQty.setEnabled(false);
			boxDiscount.setEnabled(false);
			boxTotalItem.setEnabled(false);
			btnProduct.setEnabled(false);
			btnSave.setEnabled(false);
			btnManager.setVisible(false);
			btnRePrint.setVisible(false);

		} else if (m == Library.FormMode.Open) {
			btnContact.setEnabled(false);
			btnSearch.setEnabled(true);
			txtContCode.setEnabled(false);

			btnDelItem.setEnabled(false);
			btnPayRemove.setEnabled(false);
			txtSaleDate.setEnabled(false);
			txtShipDate.setEnabled(false);
			txtDueDate.setEnabled(false);
			txtProject.setEnabled(false);
			txtPrjCode.setEnabled(false);
			txtAddr.setEnabled(false);
			txtShipTo.setEnabled(false);
			txtComment.setEnabled(false);
			txtDocRef.setEnabled(false);
			txtCustomer.setEnabled(false);
			txtCode.setEnabled(false);
			txtStatus.setEnabled(false);
			txtBalance.setEnabled(false);
			txtTotalItem.setEnabled(false);
			txtTotalVat.setEnabled(false);
			txtTotalAmt.setEnabled(false);
			txtReTotalItem.setEnabled(false);
			txtDiscount.setEnabled(false);
			boxPayAmt.setEnabled(false);
			txtPayMethod.setEnabled(false);
			txtCheck.setEnabled(false);
			txtPayMeth.setEnabled(false);
			boxCheckDate.setEnabled(false);
			txtProCode.setEnabled(false);
			txtProName.setEnabled(false);
			boxQty.setEnabled(false);
			boxDiscount.setEnabled(false);
			boxTotalItem.setEnabled(false);
			btnProduct.setEnabled(false);
			btnSave.setEnabled(false);
		} else if (m == Library.FormMode.Edit || m == Library.FormMode.Insert) {
			boxPayAmt.setEnabled(true);
			btnDelItem.setEnabled(true);
			txtPayMethod.setEnabled(true);
			txtCheck.setEnabled(true);
			txtPayMeth.setEnabled(true);
			boxCheckDate.setEnabled(true);
			txtProCode.setEnabled(false);
			txtProName.setEnabled(false);
			txtDiscount.setEnabled(true);
			if (chkUpdateStock.getValue()) {
				boxQty.setEnabled(true);
				boxDiscount.setEnabled(false);
				boxTotalItem.setEnabled(false);
			} else {
				boxQty.setEnabled(false);
				boxDiscount.setEnabled(true);
				boxTotalItem.setEnabled(true);
			}

			btnProduct.setEnabled(false);
			btnSave.setEnabled(true);
		}
	}

	protected Customer customer;

	AsyncCallback<Customer> custCallback = new AsyncCallback<Customer>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(Customer result) {
			customer = result;
			if (mode == Library.FormMode.Insert
					|| mode == Library.FormMode.Edit) {
				boolean valid = true;
				if (customer.custStatus.compareTo("2") > 0) {
					Window.alert("สถานะแก้ไขไม่ได้");
					// clearScreen();
					valid = false;
				} else if (customer.custLimit > 1
						&& customer.custBalance > customer.custLimit) {
					Window.alert("มียอดค้างชำระเกินวงเงิน");
					// clearScreen();
					valid = false;
				}
				if (valid) {
					Date today = new Date();
					invoice.contCode = result.contCode;
					invoice.contactAddr = result.contact.label;
					CalendarUtil.addDaysToDate(today, result.custDueDay);
					invoice.dueDate = today;

					// if (txtContCode.getValue().equals("999999")) {
					// txtPayMeth.setValue("1");
					// txtPayMethod.setValue("เงินสด");
					// } else {
					// txtPayMeth.setValue("0");
					// txtPayMethod.setValue("ค้างชำระ");
					// }
					refreshInvoice();
				} else {
					clearScreen();
				}
			} else {
				refreshInvoice(); // กรณีเปิดดูอย่างเดียว
			}
		}
	};

	Invoice invoice;

	AsyncCallback<String> insInvCallback = new AsyncCallback<String>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(String result) {
			// Window.alert("บันทึก " + result);
			btnSave.setEnabled(true);
			btnSave2.setEnabled(true);
			Library.getSaleService().selectInvoice(Integer.valueOf(result),
					invCallback);
		}
	};

	AsyncCallback<Invoice> invCallback = new AsyncCallback<Invoice>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(Invoice result) {
			if (result != null) {
				if (result.docuKind.equals("Q") || result.docuKind.equals("R")
						|| result.docuKind.equals("T")) {
					if (result.status.compareTo("0") > 0)
						setMode(Library.FormMode.Open);
					else
						setMode(Library.FormMode.Edit);
				} else {
					setMode(Library.FormMode.Insert);
				}
				invoice = result;
				if (invoice.contCode != null)
					Library.getSaleService().selectCustomer(invoice.contCode,
							custCallback);
				if (mode == Library.FormMode.Edit
						|| mode == Library.FormMode.Insert) {
					for (InvItem item : invoice.items) {
						// Window.alert("Total " + item.refundTotal);
						item.qty += item.refundQty;
						item.total += item.refundTotal;
						item.tmpRefundQty = 0.0;
						item.tmpDiscount = 0.0;
						item.tmpRefundTotal = item.total;
					}
					invoice.totalPaid = 0.0;
					invoice.totalAmt = 0.0;
					invoice.totalItem = 0.0;
					invoice.payments.clear();
				}
				refreshPayments();
				refreshItem();
				refreshInvoice();

			} else {
				clearScreen();
			}
		}
	};

	protected InvItem curItem;
	AsyncCallback<Product> proCallback = new AsyncCallback<Product>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(Product result) {
			if (result != null) {
				// txtProName.setText(result.name);
				// boxQty.setValue(1.0);
				// boxPrice.setValue(result.sellPrice);
				// boxDiscount.setValue(result.discount);

				if (mode == Library.FormMode.Insert
						|| mode == Library.FormMode.Edit) {
					if (curItem == null) {
						curItem = new InvItem();
						invoice.items.add(curItem);

					}
					curItem.invNo = invoice.invNo;
					curItem.proCode = result.proCode;
					curItem.qty = 1.0;
					curItem.unitPrice = result.sellPrice;
					curItem.proName = result.name;
					curItem.discount = result.discount;
					curItem.stkCode = result.stkCode;
					curItem.vat = vat.get(Integer.parseInt(result.sellVAT));
					curItem.unit = result.unit;
					curItem.product = result;
					curItem.stocks = result.stocks;
					refreshItem();
					refreshInvoice();
					boxQty.setFocus(true);
					boxQty.selectAll();
				}
			} else {
				Window.alert("ไม่มีข้อมูลสินค้า");
			}
		}
	};

	protected Payment curPay;

	public void clearScreen() {
		invoice = new Invoice();
		invoice.systemKind = "D";
		invoice.docuKind = "I";
		customer = new Customer();
		curItem = null;
		curPay = new Payment();
		curPay.payMethod = 0;
		curPay.payMethodName = "ค้างชำระ";
		txtCheck.setVisible(false);
		boxCheckDate.setVisible(false);
		label_2.setVisible(false);
		label_3.setVisible(false);
		txtRreason.setValue(null);
		txtReasonDesc.setValue(null);
		chkUpdateStock.setValue(null);
		oldTotalItem = 0;
		oldTotalVat = 0;
		oldTotalAmt = 0;
		setMode(Library.FormMode.Clear);
		refreshPayments();
		refreshItem();
		refreshInvoice();
	}

	protected void refreshInvoice() {
		txtDocRef.setText(invoice.docRef);
		txtCustomer.setText(customer.contact.name);
		txtContCode.setText(invoice.contCode);
		txtSaleDate.setValue(invoice.invDate);
		txtShipDate.setValue(invoice.shipDate);
		txtDueDate.setValue(invoice.dueDate);
		txtProject.setText(invoice.projCode);
		txtAddr.setText(invoice.contactAddr);
		txtShipTo.setText(invoice.shipTo);
		txtComment.setText(invoice.note);
		lbTextTotal.setText(invoice.totalAmtText);
		String x = Library.moneyFormat(customer.custLimit
				- customer.custBalance);
		txtBalance.setValue(x);
		txtTotalItem.setValue(Library.moneyFormat(invoice.totalItem));
		txtTotalAmt.setValue(Library.moneyFormat(invoice.totalAmt));
		txtReTotalItem.setValue(Library.moneyFormat(oldTotalItem));
		txtReTotalVat.setValue(Library.moneyFormat(oldTotalVat));
		txtReTotalAmt.setValue(Library.moneyFormat(oldTotalAmt));
		double bal = invoice.totalAmt - invoice.totalPaid;
		boxPayAmt.setValue(bal);
		// Window.alert(invoice.totalAmtText + " - " + invoice.totalPaid);
		txtTotalVat.setValue(Library.moneyFormat(invoice.totalVat));
		txtDiscount.setValue(Library.moneyFormat(invoice.spcDeduct));
		// if (invoice.totalPaid == 0) {
		// btnSave.setText("อัพโหลด");
		// } else {
		// btnSave.setText("บันทึก");
		// }
	}

	protected void refreshPayments() {
		if (mode == Library.FormMode.Insert || mode == Library.FormMode.Edit)
			calcPay();
		if (curPay == null) {
			curPay = new Payment();
			curPay.payMethod = 0;
			curPay.payMethodName = "ค้างชำระ";
			curPay.amt = invoice.totalAmt - invoice.totalPaid;
		}
		boxPayAmt.setValue(curPay.amt);
		// txtPayMeth.setText(curPay.payMethod.toString());
		txtPayMethod.setText(curPay.payMethodName);
		txtCheck.setValue(curPay.chkCardNo);
		txtPayMeth.setValue(curPay.payMethod.toString());
		boxCheckDate.setValue(curPay.checkDate);

		txtTotalItem.setText(Library.moneyFormat(invoice.totalItem));
		payData.setList(invoice.payments);
		payData.refresh();
	}

	protected void calcPay() {

	}

	protected void refreshItem() {
		if (mode == Library.FormMode.Insert || mode == Library.FormMode.Edit) {
			calcItem();
		}
		if (curItem == null) {
			txtProCode.setText(null);
			txtProName.setText(null);
			boxQty.setValue(null);
			boxDiscount.setValue(null);
			boxTotalItem.setValue(null);
		} else {
			if (chkUpdateStock.getValue()) {
				boxQty.setValue(curItem.tmpRefundQty);
				boxDiscount.setValue(curItem.tmpDiscount);
			} else {
				boxQty.setValue(curItem.qty);
				boxDiscount.setValue(curItem.tmpDiscount);
			}
			txtProCode.setText(curItem.proCode);
			txtProName.setText(curItem.proName);
			boxTotalItem.setValue(curItem.tmpRefundTotal);
			boxQty.setTitle(curItem.tmpRefundQty.toString());
			boxDiscount.setTitle(curItem.tmpDiscount.toString());
		}
		// txtTotal.setText(Library.moneyFormat(invoice.totalItem));
		// txtTotalVat.setText(Library.moneyFormat(invoice.totalVat));
		// txtTotalAmt.setText(Library.moneyFormat(invoice.totalAmt));
		// lbTextTotal.setText(Library.moneyText(invoice.totalAmt));
		itemData.setList(invoice.items);
		itemData.refresh();
	}

	protected static FormInvRefund panel;

	public static FormInvRefund getPanel() {
		if (panel == null)
			panel = GWT.create(FormInvRefund.class);
		return panel;
	}

	protected static final String pWidth = "900px";

	protected static final String pHeight = "500px";

	protected final ListDataProvider<InvItem> itemData = new ListDataProvider<InvItem>();
	protected final CellTable<InvItem> itemTable = new CellTable<InvItem>();
	protected final SingleSelectionModel<InvItem> itemSelection = new SingleSelectionModel<InvItem>();

	protected final ListDataProvider<Payment> payData = new ListDataProvider<Payment>();
	protected final CellTable<Payment> payTable = new CellTable<Payment>();
	protected final SingleSelectionModel<Payment> paySelection = new SingleSelectionModel<Payment>();

	protected List<Double> vat;

	protected final DateBox txtSaleDate;

	protected final DateBox txtShipDate;

	protected final DateBox txtDueDate;

	protected final TextBox txtProject;

	protected final TextBox txtPrjCode;

	protected final TextArea txtAddr;

	protected final TextArea txtShipTo;

	protected final TextArea txtComment;

	protected final TextBox txtDocRef;

	protected final TextBox txtCustomer;

	protected final TextBox txtCode;

	protected final TextBox txtContCode;

	protected final TextBox txtStatus;

	protected final TextBox txtBalance;

	protected final TextBox txtTotalItem;

	protected final TextBox txtTotalVat;

	protected final TextBox txtTotalAmt;

	protected final TextBox txtReTotalAmt;

	protected final TextBox txtReTotalItem;

	protected final TextBox txtDiscount;

	protected final TextBox txtReTotalVat;

	protected DoubleBox boxPayAmt = new DoubleBox();

	protected TextBox txtPayMethod = new TextBox();

	protected final TextBox txtCheck = new TextBox();

	protected final TextBox txtPayMeth = new TextBox();

	protected final DateBox boxCheckDate = new DateBox();

	protected final Button btnContact;

	protected final TextBox txtProCode = new TextBox();

	protected final TextBox txtProName = new TextBox();

	protected final DoubleBox boxQty = new DoubleBox();

	protected final DoubleBox boxDiscount = new DoubleBox();

	protected final DoubleBox boxTotalItem = new DoubleBox();

	protected final Button btnProduct = new Button("?");

	protected final Label lbFormMode;

	protected Label lbTextTotal = new Label();

	protected final Label lblDueDate;

	protected final Button btnSave = new Button("อัพโหลด");

	protected final Button btnSave2 = new Button("บันทึก");

	protected final Button btnPrint = new Button("พิมพ์");

	protected final Button btnSearch = new Button("ค้นหา");

	protected final Button btnDelItem = new Button("ลบรายการ");

	protected final Button btnPayRemove = new Button("ลบ");

	protected final Label label_2 = new Label("เลขที่เช็ค");

	protected final Label label_3 = new Label("วันที่บัตร");

	protected final TextBox txtRreason;

	protected final TextBox txtNewRefund;

	protected final Button btnManager = new Button("ถอยสเตตัส");

	protected final Button btnRePrint = new Button("พิมพ์บิลซ้ำ");

	public FormInvRefund() {
		setSize(pWidth, pHeight);

		TabPanel tabPanel = new TabPanel();
		add(tabPanel, 0, 100);
		tabPanel.setSize(pWidth, "380px");

		AbsolutePanel invPanel = new AbsolutePanel();
		tabPanel.add(createItemPanel(), "สินค้า");
		tabPanel.add(createPaymentPanel(), "ชำระเงิน");

		invPanel.setSize(pWidth, "360px");
		tabPanel.add(invPanel, "รายละเอียดบิล");

		Label label_1 = new Label("วันที่บิล");
		invPanel.add(label_1, 10, 10);

		Label label_2 = new Label("วันที่ส่งของ");
		invPanel.add(label_2, 10, 41);

		Label label_3 = new Label("วันครบกำหนด");
		invPanel.add(label_3, 10, 71);

		Label label_4 = new Label("โครงการ");
		invPanel.add(label_4, 10, 103);

		Label label_5 = new Label("ที่อยู่จัดส่ง");
		invPanel.add(label_5, 348, 103);

		Label label_6 = new Label("หมายเหตุ");
		invPanel.add(label_6, 348, 200);

		Label lblNewLabel = new Label("ที่อยู่ใบกำกับภาษี");
		invPanel.add(lblNewLabel, 352, 10);

		invPanel.add(lbTextTotal, 348, 320);
		// add(lbTextTotal, 625, 15);

		txtSaleDate = new DateBox();
		txtSaleDate.setValue(new Date());
		txtSaleDate.setFormat(new DefaultFormat(Library.DATE_FORMAT));
		invPanel.add(txtSaleDate, 114, 7);
		txtSaleDate.setSize("80px", "18px");

		txtShipDate = new DateBox();
		txtShipDate.setValue(new Date());
		txtShipDate.setFormat(new DefaultFormat(Library.DATE_FORMAT));
		invPanel.add(txtShipDate, 114, 38);
		txtShipDate.setSize("80px", "18px");

		txtDueDate = new DateBox();
		txtDueDate.setValue(new Date());
		txtDueDate.setFormat(new DefaultFormat(Library.DATE_FORMAT));
		invPanel.add(txtDueDate, 114, 68);
		txtDueDate.setSize("80px", "18px");

		lblDueDate = new Label("");
		invPanel.add(lblDueDate, 205, 70);

		txtProject = new TextBox();
		invPanel.add(txtProject, 114, 98);
		txtProject.setSize("107px", "16px");

		txtPrjCode = new TextBox();
		invPanel.add(txtPrjCode, 271, 98);
		txtPrjCode.setSize("50px", "16px");
		txtPrjCode.setVisible(false);

		Button btnProject = new Button("?");
		invPanel.add(btnProject, 235, 98);
		btnProject.setSize("30px", "24px");
		btnProject.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				LookupDialog.show("เลือก Project", "prjCode", txtPrjCode);
			}
		});

		txtAddr = new TextArea();
		invPanel.add(txtAddr, 480, 10);
		txtAddr.setSize("350px", "85px");

		txtShipTo = new TextArea();
		invPanel.add(txtShipTo, 480, 103);
		txtShipTo.setSize("350px", "85px");

		txtComment = new TextArea();
		invPanel.add(txtComment, 480, 200);
		txtComment.setSize("350px", "85px");

		txtRreason = new TextBox();
		invPanel.add(txtRreason, 114, 137);
		txtRreason.setEnabled(false);
		txtRreason.setSize("26px", "16px");

		txtReasonDesc = new TextBox();
		invPanel.add(txtReasonDesc, 114, 167);
		txtReasonDesc.setEnabled(false);
		txtReasonDesc.setSize("207px", "16px");

		chkUpdateStock = new CheckBox("update stock ?");
		chkUpdateStock.setEnabled(false);
		invPanel.add(chkUpdateStock, 177, 137);

		Label lblNewLabel_5 = new Label("เหตุผลลดหนี้");
		invPanel.add(lblNewLabel_5, 10, 137);

		txtNewRefund = new TextBox();
		add(txtNewRefund, 421, 11);
		txtNewRefund.setSize("6px", "16px");
		txtNewRefund.setVisible(false);
		txtNewRefund.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					setMode(Library.FormMode.Insert);
					Library.getSaleService().isStockUpdate(
							txtRreason.getText(), refundCallback);
					// selectContactDebter();
				}
			}
		});

		// Button btnCustomer = new Button("?");
		// invPanel.add(btnCustomer, 235, 98);
		// btnCustomer.setSize("30px", "24px");
		// btnCustomer.addClickHandler(new ClickHandler() {
		// public void onClick(ClickEvent event) {
		// LookupDialog.show("เลือกลูกค้า", "contCode", txtContCode);
		// }
		// });

		btnSave.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (invoice.payments.size() != 0)
					invoice.upload = 1;
				btnSave.setEnabled(false);
				if (mode == Library.FormMode.Insert)
					Library.getSaleService().insertInvoice(invoice,
							insInvCallback);
				else
					Library.getSaleService().updateInvoice(invoice,
							insInvCallback);
			}
		});
		add(btnSave, 806, 35);
		btnSave.setSize("88px", "30px");
		btnSave.setText("อัพโหลด");

		btnPrint.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (mode == Library.FormMode.Open) {
					if (invoice.status.compareTo("1") >= 0) {
						final Map<String, Object> params = new HashMap<String, Object>();
						params.put("invNo", invoice.invNo.toString());
						params.put("comCode", "sn");
						// Window.alert("print report");
						printReport(params);
					}
				} else {
					Window.alert("กรุณาบันทึกก่อนพิมพ์");
				}
			}
		});
		btnPrint.setText("พิมพ์");
		add(btnPrint, 806, 69);
		btnPrint.setSize("88px", "30px");

		btnSearch.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				LookupInvRefund.show("ค้นหาบิลเพื่อลดหนี้", txtNewRefund,
						txtRreason);
			}
		});

		btnSearch.setText("ทำลดหนี้");
		add(btnSearch, 10, 10);
		btnSearch.setSize("88px", "26px");

		Label label = new Label("เลขที่");
		add(label, 108, 14);
		txtDocRef = new TextBox();
		add(txtDocRef, 141, 11);
		txtDocRef.setSize("100px", "16px");

		Label label1 = new Label("ลูกค้า");
		add(label1, 108, 44);
		txtCustomer = new TextBox();
		txtCustomer.setStyleName("gwt-TextBoxR");
		txtCustomer.setReadOnly(true);
		add(txtCustomer, 234, 41);
		txtCustomer.setSize("180px", "18px");

		Label label2 = new Label("วงเงินคงเหลือ");
		add(label2, 65, 73);

		Label label4 = new Label("ลดหนี้รวม");
		label4.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
		add(label4, 440, 75);

		Label label3 = new Label("ค่าสินค้าเดิม");
		add(label3, 625, 2);

		Label lblNewLabel_1 = new Label("ลดค่าสินค้า");
		add(lblNewLabel_1, 440, 2);

		Label lblNewLabel_6 = new Label("ลดพิเศษ");
		add(lblNewLabel_6, 440, 47);

		Label label_7 = new Label("ลดภาษี");
		add(label_7, 440, 25);

		txtCode = new TextBox();
		txtCode.setReadOnly(true);
		add(txtCode, 259, 68);
		txtCode.setSize("19px", "18px");
		txtCode.setVisible(false);
		txtCode.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					Library.getSaleService().selectInvoice(
							Integer.valueOf(txtCode.getText()), invCallback);
				} else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
					clearScreen();
				} else if (event.isControlKeyDown()
						&& event.getNativeKeyCode() == ' ') {
					// btnSearchContact.click();
				}
			}
		});

		txtContCode = new TextBox();
		txtContCode.addValueChangeHandler(new ValueChangeHandler<String>() {
			public void onValueChange(ValueChangeEvent<String> event) {
				Library.getSaleService().selectCustomer(txtContCode.getText(),
						custCallback);
			}
		});
		txtContCode.setText("999999");
		add(txtContCode, 141, 41);
		txtContCode.setSize("50px", "16px");
		txtContCode.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					if (mode != Library.FormMode.Edit)
						setMode(Library.FormMode.Insert);
					Library.getSaleService().selectCustomer(
							txtContCode.getText(), custCallback);
					// selectContactDebter();
				} else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
					clearScreen();
				} else if (event.isControlKeyDown()
						&& event.getNativeKeyCode() == ' ') {
					btnContact.click();
				}
			}
		});

		btnContact = new Button("?");
		add(btnContact, 205, 41);
		btnContact.setSize("30px", "30px");
		btnContact.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				LookupDialog.show("เลือกลูกค้า", "contCode", txtContCode);
			}
		});

		txtStatus = new TextBox();
		txtStatus.setStyleName("gwt-TextBoxR");
		txtStatus.setReadOnly(true);
		add(txtStatus, 314, 70);
		txtStatus.setSize("100px", "18px");
		txtStatus.setVisible(false);

		txtBalance = new TextBox();
		txtBalance.setStyleName("gwt-TextBoxR");
		txtBalance.setText("0.0");
		txtBalance.setReadOnly(true);
		txtBalance.setMaxLength(10);
		txtBalance.setAlignment(TextAlignment.RIGHT);
		add(txtBalance, 141, 71);
		txtBalance.setSize("100px", "16px");

		txtTotalItem = new TextBox();
		txtTotalItem.setStyleName("gwt-TextBoxR");
		txtTotalItem.setText("0.0");
		txtTotalItem.setReadOnly(true);
		txtTotalItem.setMaxLength(10);
		txtTotalItem.setAlignment(TextAlignment.RIGHT);
		add(txtTotalItem, 505, 0);
		txtTotalItem.setSize("104px", "16px");

		txtTotalVat = new TextBox();
		txtTotalVat.setStyleName("gwt-TextBoxR");
		txtTotalVat.setText("0.0");
		txtTotalVat.setReadOnly(true);
		txtTotalVat.setMaxLength(10);
		txtTotalVat.setAlignment(TextAlignment.RIGHT);
		add(txtTotalVat, 505, 25);
		txtTotalVat.setSize("104px", "16px");

		txtTotalAmt = new TextBox();
		txtTotalAmt.setStyleName("gwt-TextBoxR");
		txtTotalAmt.setText("0.0");
		txtTotalAmt.setReadOnly(true);
		txtTotalAmt.setMaxLength(10);
		txtTotalAmt.setAlignment(TextAlignment.RIGHT);
		add(txtTotalAmt, 505, 75);
		txtTotalAmt.setSize("105px", "16px");

		txtReTotalItem = new TextBox();
		txtReTotalItem.setStyleName("gwt-TextBoxYellow");
		txtReTotalItem.setText("0.0");
		txtReTotalItem.setReadOnly(true);
		txtReTotalItem.setMaxLength(10);
		txtReTotalItem.setAlignment(TextAlignment.RIGHT);
		add(txtReTotalItem, 691, 2);
		txtReTotalItem.setSize("105px", "16px");

		txtDiscount = new TextBox();
		txtDiscount.setText("0.0");
		txtDiscount.setMaxLength(10);
		txtDiscount.setAlignment(TextAlignment.RIGHT);
		add(txtDiscount, 505, 48);
		txtDiscount.setSize("100px", "16px");

		lbFormMode = new Label("");
		add(lbFormMode, 260, 10);
		lbFormMode.setVisible(false);

		Button btnClear = new Button("เคลียร์");
		btnClear.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				clearScreen();
			}
		});
		add(btnClear, 10, 41);
		btnClear.setSize("88px", "26px");

		txtReTotalVat = new TextBox();
		txtReTotalVat.setText("0.0");
		txtReTotalVat.setStyleName("gwt-TextBoxYellow");
		txtReTotalVat.setReadOnly(true);
		txtReTotalVat.setMaxLength(10);
		txtReTotalVat.setAlignment(TextAlignment.RIGHT);
		add(txtReTotalVat, 691, 25);
		txtReTotalVat.setSize("105px", "16px");

		Label label_8 = new Label("ภาษี");
		add(label_8, 625, 26);
		label_8.setSize("51px", "18px");

		btnSave2.setText("บันทึก");
		add(btnSave2, 806, 2);
		btnSave2.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				// if (boxPayAmt.getValue() != 0) {
				// insertPayment();
				// }
				invoice.upload = 1;
				btnSave2.setEnabled(false);
				if (mode == Library.FormMode.Insert) {
					invoice.refundCode = Integer.parseInt(txtRreason.getValue());
					Library.getSaleService().refundInvoice(invoice,
							insInvCallback);
				}
			}
		});

		btnSave2.setSize("88px", "30px");

		txtReTotalAmt = new TextBox();
		txtReTotalAmt.setText("0.0");
		txtReTotalAmt.setStyleName("gwt-TextBoxYellow");
		txtReTotalAmt.setReadOnly(true);
		txtReTotalAmt.setMaxLength(10);
		txtReTotalAmt.setAlignment(TextAlignment.RIGHT);
		add(txtReTotalAmt, 691, 75);
		txtReTotalAmt.setSize("105px", "16px");

		Label label_9 = new Label("รวมเงิน");
		add(label_9, 625, 75);
		label_9.setSize("51px", "18px");

		btnRePrint.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				if (Window.confirm("พิมพ์บิลนี้ซ้ำหรือไม่ ?")) {
					final Map<String, Object> params = new HashMap<String, Object>();
					params.put("invNo", invoice.invNo.toString());
					params.put("comCode", "sn");
					params.put("reprint", "yes");
					printReport(params);
				}
			}
		});
		add(btnRePrint, 257, 6);
		btnRePrint.setSize("82px", "30px");

		btnManager.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				if (Window.confirm("ยกเลิกการลดหนี้ ?"))
					Library.getSaleService().rollbackInvoice(
							FormInvRefund.this.invoice.invNo, rollbackCallback);
			}
		});
		add(btnManager, 345, 6);
		btnManager.setSize("82px", "30px");

		txtDiscount.addValueChangeHandler(new ValueChangeHandler<String>() {
			public void onValueChange(ValueChangeEvent<String> event) {
				invoice.spcDeduct = Double.valueOf(txtDiscount.getValue());
				// invoice.totalAmt = invoice.totalItem + invoice.totalVat
				// + invoice.spcDeduct;
				// txtTotalAmt.setText(Library.moneyFormat(invoice.totalAmt));
				// lbTextTotal.setText(Library.moneyText(invoice.totalAmt));
				refreshItem();
				refreshInvoice();
			}
		});
		tabPanel.selectTab(0);
		Library.getStkService().selectVAT(vatCallback);
		clearScreen();
	}

	protected Panel createPaymentPanel() {
		VerticalPanel vPanel1 = new VerticalPanel();
		// paySelection
		// .addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
		// @Override
		// public void onSelectionChange(SelectionChangeEvent event) {
		// curPay = paySelection.getSelectedObject();
		// refreshPayments();
		// }
		// });

		vPanel1.setSize("100%", "100%");
		AbsolutePanel editPanel = new AbsolutePanel();
		editPanel.setSize("880px", "80px");
		vPanel1.add(editPanel);

		Label label = new Label("ชำระ");
		editPanel.add(label, 10, 10);

		boxPayAmt.setAlignment(TextAlignment.RIGHT);
		editPanel.add(boxPayAmt, 91, 7);
		boxPayAmt.setSize("100px", "18px");
		boxPayAmt.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					insertPayment();
				} else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
				} else if (event.isControlKeyDown()
						&& event.getNativeKeyCode() == ' ') {
				}
			}
		});

		Label label_1 = new Label("วิธีชำระ");
		editPanel.add(label_1, 10, 37);

		txtPayMethod.setStyleName("gwt-TextBoxR");
		txtPayMethod.setReadOnly(true);
		txtPayMethod.setText("เงินสดขาย");
		editPanel.add(txtPayMethod, 90, 34);
		txtPayMethod.setSize("180px", "18px");

		Button btnPayMeth = new Button("?");
		editPanel.add(btnPayMeth, 275, 33);
		btnPayMeth.setSize("24px", "24px");
		btnPayMeth.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				LookupDialog.show("เลือกประเภทการชำระ", "payMeth", txtPayMeth,
						txtPayMethod);
			}
		});

		ScrollPanel paymentPanel = new ScrollPanel();
		paymentPanel.setSize("895px", "280px");
		vPanel1.add(paymentPanel);

		payTable.setStyleName("table");
		paymentPanel.setWidget(payTable);

		payData.addDataDisplay(payTable);
		payTable.setPageSize(10);
		payTable.setTableLayoutFixed(true);
		payTable.setAccessKey('x');
		// itemTable.setSize("100%", "100%");
		payTable.setHeight("100%");
		// payTable.setWidth("100%", true);
		payTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);

		TextColumn<Payment> colPayDate = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				if (object.payDate == null)
					return null;
				else
					return Library.DATE_FORMAT.format(object.payDate);
			}
		};
		payTable.addColumn(colPayDate, "วันที่ชำระเงิน");
		payTable.setColumnWidth(colPayDate, "100px");

		TextColumn<Payment> colPayMeth = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				return object.payMethodName;
			}
		};
		payTable.addColumn(colPayMeth, "วิธีชำระ");
		payTable.setColumnWidth(colPayMeth, "150px");

		TextColumn<Payment> colPayAmt = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				return Library.moneyFormat(object.amt);
			}
		};
		colPayAmt.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		payTable.addColumn(colPayAmt, "Amount");
		payTable.setColumnWidth(colPayAmt, "50px");

		TextColumn<Payment> colCard = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				return object.chkCardNo;
			}
		};
		payTable.addColumn(colCard, "เลขที่เช็ค/บัตร");
		payTable.setColumnWidth(colCard, "100px");

		TextColumn<Payment> colExpDate = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				if (object.checkDate == null)
					return null;
				else
					return Library.DATE_FORMAT.format(object.checkDate);
			}
		};
		payTable.addColumn(colExpDate, "วันที่เช็ค");
		payTable.setColumnWidth(colExpDate, "100px");

		editPanel.add(txtCheck, 473, 6);
		txtCheck.setSize("100px", "18px");
		txtCheck.setVisible(false);

		label_2.setVisible(false);

		editPanel.add(label_2, 392, 10);

		txtPayMeth.setReadOnly(true);
		txtPayMeth.setVisible(false);
		editPanel.add(txtPayMeth, 252, 33);
		txtPayMeth.setSize("20px", "18px");
		txtPayMeth.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				txtCheck.setVisible(txtPayMeth.getText().equals("2"));
				label_2.setVisible(txtCheck.isVisible());
				boxCheckDate.setVisible(txtPayMeth.getText().equals("2")
						|| txtPayMeth.getText().equals("3")
						|| txtPayMeth.getText().equals("4")
						|| txtPayMeth.getText().equals("5")
						|| txtPayMeth.getText().equals("6")
						|| txtPayMeth.getText().equals("7")
						|| txtPayMeth.getText().compareTo("22") >= 0);
				label_3.setVisible(boxCheckDate.isVisible());
				if (txtPayMeth.getText().equals("2")) {
					label_3.setText("วันที่เช็ค");
				}
				if (txtPayMeth.getText().equals("3")
						|| txtPayMeth.getText().equals("4")
						|| txtPayMeth.getText().equals("5")
						|| txtPayMeth.getText().equals("6")) {
					label_3.setText("วันที่บัตรเครดิต");
				}
				if (txtPayMeth.getText().equals("7")
						|| txtPayMeth.getText().compareTo("22") >= 0) {
					label_3.setText("วันที่โอน");
				}
			}
		});

		editPanel.add(label_3, 392, 37);
		label_3.setSize("120px", "18px");
		label_3.setVisible(false);

		boxCheckDate.setFormat(new DefaultFormat(Library.DATE_FORMAT));
		editPanel.add(boxCheckDate, 473, 34);
		boxCheckDate.setSize("105px", "18px");
		boxCheckDate.setVisible(false);

		Button btnPay = new Button("ยืนยันชำระ");
		btnPay.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				insertPayment();
			}
		});

		editPanel.add(btnPay, 720, 7);
		btnPay.setSize("90px", "24px");

		btnPayRemove.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				deletePayment();
			}

		});
		btnPayRemove.setTabIndex(-1);

		editPanel.add(btnPayRemove, 720, 40);
		btnPayRemove.setSize("90px", "24px");

		payTable.setSelectionModel(paySelection);

		// paySelection
		// .addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
		// @Override
		// public void onSelectionChange(SelectionChangeEvent event) {
		// curPay = paySelection.getSelectedObject();
		// refreshPayments();
		// }
		// });

		// DoubleBox doubleBox = new DoubleBox();
		// editPanel.add(doubleBox, 95, 10);
		//
		// TextBox textBox = new TextBox();
		// editPanel.add(textBox, 91, 42);
		//
		// Label lblNewLabel_5 = new Label("ส่วนลดพิเศษ");
		// editPanel.add(lblNewLabel_5, 10, 10);
		return vPanel1;
	}

	protected Panel createItemPanel() {
		VerticalPanel vPanel = new VerticalPanel();
		vPanel.setSize("100%", "100%");
		AbsolutePanel editPanel = new AbsolutePanel();
		editPanel.setSize("895px", "80px");
		vPanel.add(editPanel);
		ScrollPanel listPanel = new ScrollPanel();
		listPanel.setSize("895px", "280px");
		vPanel.add(listPanel);

		itemTable.setStyleName("table");
		listPanel.setWidget(itemTable);
		itemTable.setSelectionModel(itemSelection);

		itemSelection
				.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
					@Override
					public void onSelectionChange(SelectionChangeEvent event) {
						curItem = itemSelection.getSelectedObject();
						refreshItem();
					}
				});

		TextColumn<InvItem> colProCode = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return object.proCode;
			}
		};
		// colProCode.setCellStyleNames("table");
		itemTable.addColumn(colProCode, "รหัสสินค้า");
		itemTable.setColumnWidth(colProCode, "95px");

		// TextColumn<InvItem> colStkLoc = new TextColumn<InvItem>() {
		// @Override
		// public String getValue(InvItem object) {
		// return object.stkCode;
		// }
		// };
		// colProCode.setCellStyleNames("table");
		// itemTable.addColumn(colStkLoc, "คลัง");
		// itemTable.setColumnWidth(colStkLoc, "35px");

		TextColumn<InvItem> colProName = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return object.proName;
			}
		};

		itemTable.addColumn(colProName, "ชื่อสินค้า");
		itemTable.setColumnWidth(colProName, "200px");

		TextColumn<InvItem> colQty = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				if (object.qty == null)
					object.qty = 0.0;
				return String.valueOf(object.qty);
			}
		};
		colQty.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		itemTable.addColumn(colQty, "จำนวน");
		itemTable.setColumnWidth(colQty, "40px");

		TextColumn<InvItem> colTmpQty = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				if (object.tmpRefundQty == null)
					object.tmpRefundQty = 0.0;
				return String.valueOf(object.tmpRefundQty);
			}
		};
		colTmpQty.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		itemTable.addColumn(colTmpQty, "ลดหนี้");
		itemTable.setColumnWidth(colTmpQty, "50px");

		TextColumn<InvItem> colUnitPrice = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return Library.moneyFormat(object.unitPrice);
			}
		};
		colUnitPrice.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		itemTable.addColumn(colUnitPrice, "ราคา/หน่วย");
		itemTable.setColumnWidth(colUnitPrice, "55px");

		TextColumn<InvItem> colTmpUnitPrice = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return Library.moneyFormat(object.tmpDiscount);
			}
		};
		colTmpUnitPrice
				.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		itemTable.addColumn(colTmpUnitPrice, "ส่วนลดใหม่");
		itemTable.setColumnWidth(colTmpUnitPrice, "55px");

		/*
		 * TextColumn<InvItem> colUnit = new TextColumn<InvItem>() {
		 * 
		 * @Override public String getValue(InvItem object) { return
		 * object.unit; } }; itemTable.addColumn(colUnit, "หน่วย");
		 * itemTable.setColumnWidth(colUnit, "40px");
		 */
		TextColumn<InvItem> colDisc = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return String.valueOf(object.discount);
			}
		};
		colDisc.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		itemTable.addColumn(colDisc, "ลด%");
		itemTable.setColumnWidth(colDisc, "55px");

		TextColumn<InvItem> colTotalItem = new TextColumn<InvItem>() {
			@Override
			public String getValue(InvItem object) {
				return Library.moneyFormat(object.tmpRefundTotal);
			}
		};
		colTotalItem.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		itemTable.addColumn(colTotalItem, "รวม");
		itemTable.setColumnWidth(colTotalItem, "80px");

		// itemData.setList(itemList);
		itemData.addDataDisplay(itemTable);
		itemTable.setPageSize(40);
		itemTable.setTableLayoutFixed(true);
		itemTable.setAccessKey('x');
		itemTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
		itemTable.setHeight("100%");
		itemTable.setWidth("100%", true);

		btnProduct.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				LookupDialog.show("เลือกสินค้า", "proCode", txtProCode);
			}
		});
		editPanel.add(btnProduct, 204, 4);
		btnProduct.setSize("27px", "24px");

		editPanel.add(txtProCode, 70, 4);
		txtProCode.setSize("120px", "18px");
		txtProCode.addValueChangeHandler(new ValueChangeHandler<String>() {
			public void onValueChange(ValueChangeEvent<String> event) {
				Library.getStkService().selectProduct(txtProCode.getText(),
						proCallback);
			}
		});

		txtProCode.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					curItem = findList(txtProCode.getText());
					if (curItem == null) {
						Library.getStkService().selectProduct(
								txtProCode.getText(), proCallback);
					} else {
						curItem.qty++;
						refreshItem();
						refreshInvoice();
					}
				} else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
					curItem = null;
					refreshItem();
				} else if (event.isControlKeyDown()
						&& event.getNativeKeyCode() == ' ') {
					btnProduct.click();
				}
			}
		});
		Label lblNewLabel_2 = new Label("รหัสสินค้า");
		editPanel.add(lblNewLabel_2, 8, 9);

		editPanel.add(txtProName, 330, 4);
		txtProName.setSize("337px", "18px");

		Label lblNewLabel_3 = new Label("ชื่อสินค้า");
		editPanel.add(lblNewLabel_3, 260, 10);

		Label lblNewLabel_4 = new Label("จำนวน");
		editPanel.add(lblNewLabel_4, 8, 39);

		editPanel.add(boxQty, 70, 36);
		boxQty.setSize("50px", "18px");
		boxQty.setAlignment(TextAlignment.RIGHT);
		boxQty.addValueChangeHandler(new ValueChangeHandler<Double>() {
			@Override
			public void onValueChange(ValueChangeEvent<Double> event) {
				curItem.tmpRefundQty = event.getValue();
				curItem.edited = true;
				refreshItem();
				refreshInvoice();
			}
		});
		boxQty.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					boxDiscount.setFocus(true);
					boxDiscount.selectAll();
				}
			}
		});

		Label label = new Label("ลด(%)");
		editPanel.add(label, 170, 39);

		editPanel.add(boxDiscount, 220, 36);
		boxDiscount.setSize("50px", "18px");
		boxDiscount.setAlignment(TextAlignment.RIGHT);
		boxDiscount.addValueChangeHandler(new ValueChangeHandler<Double>() {
			@Override
			public void onValueChange(ValueChangeEvent<Double> event) {
				curItem.calcPriceBack = false;
				curItem.edited = true;
				curItem.tmpDiscount = event.getValue();
				refreshItem();
				refreshInvoice();

			}
		});
		boxDiscount.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					boxTotalItem.setFocus(true);
					boxTotalItem.selectAll();
				}
			}
		});

		Label label1 = new Label("รวม");
		editPanel.add(label1, 302, 39);
		boxTotalItem.setAlignment(TextAlignment.RIGHT);

		editPanel.add(boxTotalItem, 330, 36);
		boxTotalItem.setSize("96px", "18px");
		boxTotalItem.addValueChangeHandler(new ValueChangeHandler<Double>() {
			@Override
			public void onValueChange(ValueChangeEvent<Double> event) {
				curItem.tmpRefundTotal = event.getValue();
				curItem.calcPriceBack = true;
				curItem.edited = true;
				refreshItem();
				refreshInvoice();

			}
		});
		// StockPopup.popup.setTable(itemTable);

		btnDelItem.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (mode == Library.FormMode.Insert
						|| mode == Library.FormMode.Edit) {
					invoice.items.remove(curItem);
					curItem = null;
					refreshItem();
					refreshInvoice();
				}
			}
		});
		editPanel.add(btnDelItem, 700, 36);
		btnDelItem.setSize("100px", "24px");
		btnDelItem.setVisible(false);
		return vPanel;
	}

	protected InvItem findList(String proCode) {
		InvItem invitem = null;
		if (invoice.items.size() > 0) {
			int i = invoice.items.size() - 1;
			// for (int i = itemList.size() - 1; i >= 0 && invitem == null; i--)
			if (invoice.items.get(i).proCode.equals(proCode))
				invitem = invoice.items.get(i);
		}
		if (invitem != null)
			itemSelection.setSelected(invitem, true);
		return invitem;
	}

	@Override
	public void execute(int execode) {
		// TODO Auto-generated method stub
	}

	protected void calcItem() {
		int i = 0;
		invoice.totalVat = 0.0;
		invoice.totalAmt = 0.0;
		invoice.totalItem = 0.0;
		oldTotalVat = 0;
		oldTotalItem = 0;
		oldTotalAmt = 0;

		double price;
		double totalItem = 0;
		for (InvItem item : invoice.items)
			if (item.edited) {
				if (chkUpdateStock.getValue()) {
					if (item.tmpRefundQty > 0)
						item.tmpRefundQty *= -1;
					if ((item.tmpRefundQty + item.qty) < 0) {
						item.tmpRefundQty = -item.qty;
						Window.alert("ลดหนี้เกินจำนวนในบิล " + item.qty);
					}
					totalItem = item.tmpRefundQty * item.unitPrice;
				} else {
					if (item.tmpDiscount > 100) {
						item.tmpDiscount = 100.0;
						Window.alert("ลดหนี้เกิน 100%");
					}
					if (item.tmpRefundTotal > item.total
							&& item.tmpRefundTotal < 0) {
						item.tmpRefundTotal = item.total;
						Window.alert("ลดหนี้เกินราคาในบิล "
								+ Library.moneyFormat(item.total));
					}
					if (item.calcPriceBack) {
						totalItem = item.tmpRefundTotal;
						// Window.alert("CalcPriceBack");
					} else {
						totalItem = item.qty * item.unitPrice;
						// Window.alert("totalItem=" + totalItem);
					}
				}

				// if (item.dcLevel > 0)
				// item.discount = Library.discountSeries(item.product,
				// item.dcLevel);
				// item.item = ++i;
				// totalItem = item.qty * item.unitPrice;
				// if (item.product.minPrice > 0
				// && item.unitPrice < item.product.minPrice)
				// item.unitPrice = item.product.minPrice;

				if (item.calcPriceBack) {
					// Window.alert("calcPriceBack");
					double total = item.unitPrice * item.qty;
					item.discount = (total - item.tmpRefundTotal) / total * 100;
				} else {
					price = totalItem * ((100 - item.discount) / 100)
							* ((100 - item.refundPrc) / 100);
					// price = totalItem;
					price -= price * item.tmpDiscount / 100;
					// item.discount = item.tmpDiscount;
					price *= 100;
					item.tmpRefundTotal = Math.round(price) / 100.0;
				}

				// Window.alert("Total : " + item.total);
				// item.vatAmt = item.total * item.vat;
				item.tmpVatAmt = item.tmpRefundTotal * item.vat;
				invoice.totalItem += item.tmpRefundTotal;
				invoice.totalVat += item.tmpVatAmt;

				oldTotalItem += item.total;
				oldTotalVat += item.total * item.vat;
			}

		invoice.totalAmt = invoice.totalVat + invoice.totalItem
				+ invoice.spcDeduct;
		oldTotalAmt = oldTotalItem + oldTotalVat;

		if (!chkUpdateStock.getValue()) {
			invoice.totalAmt -= oldTotalAmt;
			invoice.totalVat -= oldTotalVat;
			invoice.totalItem -= oldTotalItem;
		}

		invoice.totalVat = Math.round(invoice.totalVat * 100) / 100.0;
		// invoice.totalItem = invoice.totalAmt - invoice.totalVat;
		invoice.totalAmt = Math.round(invoice.totalAmt * 100) / 100.0;
		invoice.totalAmt -= invoice.spcDeduct;
		invoice.totalAmtText = Library.moneyText(invoice.totalAmt);
		// InvItem item = itemSelection.getSelectedObject();
		// if (item == null && itemList.size() > 0)
		// itemSelection.setSelected(itemList.get(0), true);
		// item = itemSelection.getSelectedObject();
	}

	AsyncCallback<List<Double>> vatCallback = new AsyncCallback<List<Double>>() {

		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(List<Double> result) {
			if (result != null) {
				vat = result;
			}

		}
	};

	protected void insertPayment() {
		if (mode == Library.FormMode.Insert || mode == Library.FormMode.Edit) {
			if ((txtCheck.getText() != null || !txtCheck.isVisible())
					&& (boxCheckDate.getValue() != null || !boxCheckDate
							.isVisible())) {
				curPay.amt = boxPayAmt.getValue();
				if (curPay == null && curPay.amt == null)
					curPay.amt = 0.0;
				// curPay.payDate = boxCheckDate.getValue();
				curPay.checkDate = boxCheckDate.getValue();
				curPay.payMethod = Integer.parseInt(txtPayMeth.getText());
				curPay.payMethodName = txtPayMethod.getText();
				curPay.chkCardNo = txtCheck.getText();
				curPay.systemKind = invoice.systemKind;
				Double balance = customer.custLimit - customer.custBalance;
				if (curPay.payMethod == 0 && curPay.amt.compareTo(balance) > 0) {

					Window.alert("เกินวงเงินค้างชำระ "
							+ Library.moneyFormat(curPay.amt));
				} else {
					double paid = 0;
					for (Payment p : invoice.payments)
						paid += p.amt;
					double x = invoice.totalAmt - paid;
					if (Library.compare(curPay.amt, x) <= 0) {
						if (curPay.payMethod != 0)
							invoice.totalPaid += curPay.amt;
						invoice.payments.add(curPay);
						curPay = null;
						refreshPayments();
						refreshInvoice();
					} else {
						Window.alert("ชำระเกินยอดบิล " + Library.moneyFormat(x));
					}
				}
			} else {
				Window.alert("ข้อมูลการชำระไม่ครบ");
			}
		}
	}

	protected void deletePayment() {
		if (mode == Library.FormMode.Insert || mode == Library.FormMode.Edit) {
			invoice.payments.remove(curPay);
			if (curPay.payMethod != null && !curPay.payMethod.equals("00"))
				invoice.totalPaid -= curPay.amt;
			refreshPayments();
			refreshInvoice();
		}
	}

	AsyncCallback<RReason> refundCallback = new AsyncCallback<RReason>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(RReason result) {
			if (result != null) {
				txtRreason.setValue(result.resCode.toString());
				txtReasonDesc.setValue(result.descript);
				chkUpdateStock.setValue(result.stockUpdate);
				Library.getSaleService().selectInvoice(
						Integer.valueOf(txtNewRefund.getText()), invCallback);

			} else {
				clearScreen();
			}
		}
	};

	protected final TextBox txtReasonDesc;

	protected final CheckBox chkUpdateStock;

	private double oldTotalItem;
	private double oldTotalVat;
	private double oldTotalAmt;

	private AsyncCallback<String> reportCallback = new AsyncCallback<String>() {
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(String result) {
			// Window.open(Window.Location.getPath()
			// + "applet/report.jsp?sessionReport=" + result, "APPLET",
			// "features");

			Window.open(
					Window.Location.getPath() + "output/" + result + ".pdf",
					"PDF", "features");

		}
	};

	AsyncCallback<Boolean> rollbackCallback = new AsyncCallback<Boolean>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(Boolean result) {
			if (result) {
				int invNo = Integer.valueOf(txtCode.getText());
				clearScreen();
				Library.getSaleService().selectInvoice(invNo, invCallback);
			} else
				Window.alert("การถอยสถานะทำไม่สำเร็จ!");
		}
	};

	public void printReport(final Map<String, Object> params) {
		if (invoice.docuKind.equals("R"))
			Library.getService().fillReport("report008.jasper", params,
					reportCallback);
		else if (invoice.docuKind.equals("Q"))
			Library.getService().fillReport("report009.jasper", params,
					reportCallback);
		else if (invoice.docuKind.equals("T"))
			Library.getService().fillReport("report010.jasper", params,
					reportCallback);
	}
}
